from Tkinter import *
from khronos.utils import Namespace

class TabbedWindow(Frame):
    def __init__(self, master, tab_side=LEFT):
        Frame.__init__(self, master)
        self.seq_no = 0         # sequence number used to assign ids to tabs
        self.tabs = {}          # mapping of tab titles to tabs
        self.tab_index = {}     # mapping of ids to tabs (child frames)
        self.button_index = {}  # mapping of ids to tab buttons
        self.tab_id = IntVar(0) # id of active tab
        self.active = None      # currently active tab
        self.tabbutton_pack_side = LEFT if tab_side in (TOP, BOTTOM) else TOP
        self.build()
        self.layout(tab_side)
        
    def __getitem__(self, tab_title):
        return self.tabs[tab_title]
        
    def build(self):
        w = self.widgets = Namespace()
        w.tabs = Frame(self, borderwidth=1)
        w.main = Frame(self, borderwidth=1)
        
    def layout(self, tab_side):
        tab_row, tab_col, main_row, main_col = {TOP: (0, 0, 1, 0), 
                                                BOTTOM: (1, 0, 0, 0), 
                                                LEFT: (0, 0, 0, 1), 
                                                RIGHT: (0, 1, 0, 0)}[tab_side]
        self.rowconfigure(main_row, weight=1)
        self.columnconfigure(main_col, weight=1)
        
        w = self.widgets
        w.tabs.grid(row=tab_row, column=tab_col, sticky=N+S+E+W)
        w.main.grid(row=main_row, column=main_col, sticky=N+S+E+W)
        
    def add(self, child, title):
        tab_id = self.seq_no
        self.seq_no += 1
        self.tab_index[tab_id] = child
        self.tabs[title] = child
        rb = Radiobutton(self.widgets.tabs, text=title, indicatoron=0, 
                         variable=self.tab_id, value=tab_id, 
                         command=self.show_tab)
        rb.pack(fill=BOTH, side=self.tabbutton_pack_side)
        self.button_index[tab_id] = rb
        if self.active is None:
            self.show_tab(tab_id)
        return tab_id
        
    def remove(self, child):
        for tab_id, tab in self.tab_index.iteritems():
            if tab is child:
                self.pop(tab_id)
                for name, tab in self.tabs.iteritems():
                    if tab is child:
                        self.tabs.pop(name)
                        return
        raise ValueError("unable to find tab")
        
    def pop(self, tab_id):
        raise NotImplementedError()
        
    def get_id(self, tab):
        for tab_id, child in self.tab_index.iteritems():
            if tab is child:
                return tab_id
        raise ValueError("tab not found")
        
    def show_tab(self, tab_id=None):
        if self.active is not None:
            self.active.forget()
        if tab_id is None:
            tab_id = self.tab_id.get()
        self.active = self.tab_index[tab_id]
        self.active.pack(fill=BOTH, expand=True)
        self.button_index[tab_id].select()
        
